﻿using Microsoft.CodeDom.Providers.DotNetCompilerPlatform;
using Models;
using Newtonsoft.Json;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web.Services;

namespace SCService
{
    /// <summary>
    /// MainService 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务，请取消注释以下行。 
    // [System.Web.Script.Services.ScriptService]
    public class MainService : System.Web.Services.WebService
    {
        private Dictionary<string, IBusiness> _binessList = new Dictionary<string, IBusiness>();
        // 兼容性强 版本切换之后往往也要切换webservice，不然接口不一样会报错；新本版兼容性强，不用切换版本。版本回退，版本升级 按原先的方法很难找到匹配的webservice。
        // 减少开发量？不会
        // 统一接口 统一调用方式.不用去记忆那么多的接口。按照原先的方法，会有多个asmx，每个asmx有多个方法。
        // 同样的业务 不用去新增接口 较少代码开发量 比如数据库增删改查
        // 
        [WebMethod(Description = "统一接口")]
        public string ExecuteFuntion(string requeststring)
        {
            try
            {
                Request request = JsonConvert.DeserializeObject<Request>(requeststring);
                if (!_binessList.Keys.Any(x => x == request.Header.ToString()))
                {
                    // todo 异常判断没做
                    Assembly assembly = Assembly.GetExecutingAssembly(); // 获取当前程序集 
                    dynamic obj = assembly.CreateInstance("SCService.Busnisses." + request.Header.ToString());
                    if (obj != null)
                    {
                        _binessList.Add(request.Header.ToString(), (IBusiness)obj);
                    }
                    else
                    {
                        string scriptstring = File.ReadAllText(@"Script\" + request.Header.ToString());
                        CodeDomProvider compiler = new CSharpCodeProvider();     //编译器
                        CompilerParameters comPara = new CompilerParameters();   //编译器参数
                        comPara.GenerateExecutable = false; // 生成exe文件
                        comPara.GenerateInMemory = true; // 是否在内存在输出
                        CompilerResults compilerResults = compiler.CompileAssemblyFromSource(comPara, scriptstring);
                        if (compilerResults.NativeCompilerReturnValue == 0)
                        {
                            assembly = compilerResults.CompiledAssembly;
                            obj = assembly.CreateInstance("SCService.Busnisses." + request.Header.ToString());

                            _binessList.Add(request.Header.ToString(), (IBusiness)obj);
                        }
                        else
                        {
                            return (new Response() { Success = false, Message = compilerResults.ToString() }).ToJsonString();
                        }
                    }
                }
                IBusiness business = _binessList[request.Header.ToString()];
                return business.Execute(request.Data);
            }
            catch (Exception ex)
            {
                return (new Response() { Success = false, Message = ex.ToString() }).ToJsonString();
            }
        }

        [WebMethod(Description = "新增或修改接口")]
        public string AddInterface(string header, string requeststring)
        {
            try
            {
                CodeDomProvider compiler = new CSharpCodeProvider();     //编译器
                CompilerParameters comPara = new CompilerParameters();   //编译器参数




                comPara.GenerateExecutable = false; // 生成exe文件
                comPara.GenerateInMemory = true; // 是否在内存在输出
                //comPara.OutputAssembly = "SimpleCompile.exe"; // 输出文件 




                CompilerResults compilerResults = compiler.CompileAssemblyFromSource(comPara, requeststring);
                if (compilerResults.NativeCompilerReturnValue == 0)
                {
                    if (!Directory.Exists(@"Script"))
                    {
                        Directory.CreateDirectory(@"Script");
                    }
                    // 判断设置文件是否存在
                    //if (!File.Exists(@"Script\" + header +".srcipt"))
                    {
                        File.WriteAllText(@"Script\" + header + ".srcipt", requeststring);
                    }
                    return (new Response() { Success = true }).ToJsonString();
                }
                else
                {
                    string errors = "";
                    if (compilerResults.Errors.Count > 0)
                    {
                        foreach (CompilerError ce in compilerResults.Errors)
                        {
                            errors+= ce.ToString();
                        }
                    }
                    return (new Response() { Success = false, Message = errors }).ToJsonString();
                }
            }
            catch (Exception ex)
            {
                return (new Response() { Success = false, Message = ex.ToString() }).ToJsonString();
            }
        }

        [WebMethod(Description = "检查更新")]
        public string CheckUpdate(string file, string version)
        {
            try
            {
                FileStream fs = null;
                //string CurrentUploadFolderPath = Server.MapPath(ConfigurationManager.AppSettings["UploadFileFolder"]);
                string CurrentUploadFilePath = System.AppDomain.CurrentDomain.BaseDirectory + "Modules\\" + file;
                FileInfo file1 = new FileInfo(CurrentUploadFilePath);
                if (!file1.Exists)
                    return new Response<byte[]>() { Success = false, Message = $"服务器上不存在此文件:{CurrentUploadFilePath}" }.ToJsonString();// todo 错误要等级 要解决方案，要描述

                Assembly assembly = Assembly.LoadFile(CurrentUploadFilePath);
                if (assembly == null)
                    return new Response<byte[]>() { Success = false, Message = $"服务器上不存在此文件:{CurrentUploadFilePath}" }.ToJsonString();// todo 错误要等级 要解决方案，要描述


                AssemblyName assemblyName = assembly.GetName();
                string localversion = assemblyName.Version.ToString();


                if (localversion != version)
                {
                    try
                    {
                        ///打开现有文件以进行读取。
                        fs = File.OpenRead(CurrentUploadFilePath);
                        int b1;
                        System.IO.MemoryStream tempStream = new System.IO.MemoryStream();
                        while ((b1 = fs.ReadByte()) != -1)
                        {
                            tempStream.WriteByte(((byte)b1));
                        }
                        return new Response<byte[]>() { Success = true, Data = tempStream.ToArray() }.ToJsonString();
                    }
                    catch (Exception ex)
                    {
                        return new Response<byte[]>() { Success = false, Message = $"体系错误:{ex.ToString()}" }.ToJsonString();
                    }
                    finally
                    {
                        fs.Close();
                    }
                }
                else
                {
                    return new Response<byte[]>() { Success = true, Message = $"版本一致" }.ToJsonString();
                }
            }
            catch (Exception ex)
            {
                return new Response<byte[]>() { Success = false, Message = $"体系错误:{ex.ToString()}" }.ToJsonString();
            }
        }

    }
}
